﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Xml;
using UDS.Components;

namespace UDS.SubModule.WorkAttendance
{
    /// <summary>
    /// ShowDay 的摘要说明。
    /// </summary>
    public partial class ShowDayPage : Page
    {
        private DateTime _beginTime;
        private DateTime _endTime;

        protected override void OnInit(EventArgs e)
        {
            if (!DateTime.TryParse(Request.QueryString["begintime"], out _beginTime))
            {
                _beginTime = DateTime.Now;
            }
            if (!DateTime.TryParse(Request.QueryString["endtime"], out _endTime))
            {
                _endTime = DateTime.Now;
            }

            btnSubmit.Click += btnsubmit_Click;
            base.OnInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                BindData(_beginTime, _endTime);
            }

            base.OnLoad(e);
        }

        private static void AddCellToRow(HtmlTable table, ref HtmlTableRow row, HtmlTableCell cell)
        {
            if (row == null || row.Cells.Count == 7)
            {
                // Adds a new row.
                row = new HtmlTableRow();
                table.Rows.Add(row);
            }

            row.Cells.Add(cell);
        }

        private void BindData(DateTime begintime, DateTime endtime)
        {
            // Remove all rows from the table first
            while (dayTable.Rows.Count > 1)
            {
                dayTable.Rows.RemoveAt(dayTable.Rows.Count - 1);
            }

            var db = new Database();
            var prams = new[]
            {
                Database.MakeInParam("@begintime", SqlDbType.DateTime, 8, begintime),
                Database.MakeInParam("@endtime", SqlDbType.DateTime, 8, endtime)
            };

            HtmlTableRow currentRow = null;
            using (SqlDataReader dr = db.RunDataReader("dbo.sproc_WA_GetDayData", prams))
            {
                int lastDayValue = -1;
                while (dr.Read())
                {
                    var dayValue = (int)dr["DayValue"];
                    bool needDuty = Convert.ToBoolean(dr["NeedDuty"]);
                    DateTime dateTime = WA_Duty.FromDayValue(dayValue);

                    // Adds empty cells before the first day if needed
                    if (lastDayValue == -1)
                    {
                        /*
                         *  DayOfWeek
                         *  - Sunday: 0
                         *  - Monday: 1
                         *  ...
                         *  - Saturday: 6
                         */
                        int columnIndex = (int)dateTime.DayOfWeek - 1;
                        if (columnIndex == -1)
                        {
                            columnIndex = 6; // Sunday
                        }

                        for (int i = 0; i < columnIndex; i++)
                        {
                            var emptyCell = new HtmlTableCell();
                            emptyCell.InnerHtml = "&nbsp;";
                            AddCellToRow(dayTable, ref currentRow, emptyCell);
                        }
                    }
                    else
                    {
                        // If there is a gap between the current day and the last day,
                        // Fill it with empty cells.
                        while (true)
                        {
                            DateTime lastDay = WA_Duty.FromDayValue(lastDayValue);
                            lastDayValue = WA_Duty.GetDayValue(lastDay.AddDays(1));
                            if (lastDayValue >= dayValue)
                            {
                                break;
                            }

                            var emptyCell = new HtmlTableCell();
                            emptyCell.InnerHtml = "&nbsp;";
                            AddCellToRow(dayTable, ref currentRow, emptyCell);
                        }
                    }

                    // Adds the current day to the table
                    var cell = new HtmlTableCell();
                    cell.InnerText = dateTime.ToString("yyyy-MM-dd");
                    cell.Attributes["onclick"] = "Click_Cell(this);";
                    cell.Attributes["class"] = needDuty ? "onduty" : "offduty";
                    cell.Attributes["DayValue"] = dayValue.ToString();
                    AddCellToRow(dayTable, ref currentRow, cell);

                    lastDayValue = dayValue;
                }
            }
            // Adds trailing cells
            if (currentRow != null)
            {
                while (currentRow.Cells.Count != 7)
                {
                    var emptyCell = new HtmlTableCell();
                    emptyCell.InnerHtml = "&nbsp;";
                    AddCellToRow(dayTable, ref currentRow, emptyCell);
                }
            }
        }

        private void btnsubmit_Click(object sender, EventArgs e)
        {
            string hiddenValue = hfCellStatus.Value;
            if (string.IsNullOrEmpty(hiddenValue))
            {
                goto RELOAD_DAY_SETTINGS;
            }

            /*
             * XML Format
             * <settings>
             *  <day value="" needDuty="" />
             *  ...
             * </settings>
             */
            string[] array = hiddenValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (array.Length > 0)
            {
                WriteElement w = delegate(XmlWriter writer, object obj)
                {
                    string[] items = ((string)obj).Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                    if (items.Length == 2)
                    {
                        writer.WriteStartElement("day");
                        writer.WriteAttributeString("value", int.Parse(items[0]).ToString());
                        writer.WriteAttributeString("needDuty", XmlConvert.ToString(bool.Parse(items[1])));
                        writer.WriteEndElement();
                    }
                };

                string xml = Utility.GenerateXML(array, "settings", w);
                using (var db = new Database())
                {
                    var parameters = new[]
                    {
                        Database.MakeInParam("@day_xml", SqlDbType.Xml, -1, xml),
                    };

                    db.RunProc("dbo.sproc_WA_ChangeDaySetting", parameters);
                }
            }

        RELOAD_DAY_SETTINGS:
            hfCellStatus.Value = "";
            BindData(_beginTime, _endTime);
        }
    }
}